import Container from "@/component/Container"
import Match from "@/component/Matching"
import { Input } from "antd"
import { useRouter } from "next/dist/client/router"
import React, { useCallback, useEffect, useState } from "react"
import styled from "styled-components"
const ConnectCard = styled(Container)`
    max-width:600px;
    margin-top:50px;
    margin-bottom:50px;
    background:#fff;
    border-radius:10px;
`
const useSocket = () => {
    const [ws, setWs] = useState<WebSocket>(null)
    const [message, setMessage] = useState(null)
    const [state, setState] = useState(false)
    const client = useCallback((url, pushMessage = {}) => {
        if(!!ws){
            ws.close()
        }
        const w = new WebSocket(url)
        w.onopen = async () => {
            setState(true)
            setWs(w)
            if (!!pushMessage && typeof pushMessage === "object") {
                w.send(JSON.stringify(pushMessage))
            }
        }
        w.onerror = () => {
            setState(false)
        }
        w.onmessage = (msg) => {
            console.log(msg.data, "onMessage")
            setMessage(JSON.parse(msg.data))
        }
    }, [])
    const send = useCallback((obj) => {
        console.log(obj, "send")
        ws.send(JSON.stringify(obj))
    }, [ws])
    const close = useCallback(() => {
        ws.close()
        setState(false)
    }, [ws])
    return { message, client, close, send, state }
}
export type ComponentProps = {
    message: { command: string } & { [t in string]: any },
    send: <T extends object>(data: T) => void,
    close: () => void,
}
type ComponentType = (props: ComponentProps) => JSX.Element
export const withSocket = (Component: ComponentType, maxNumber: number) => {
    const result = (props) => {
        const { asPath } = useRouter()
        const { message, client, close, state, send } = useSocket()
        const [room, setRoom] = useState("")
        const [userState, setUserState] = useState<any>({
            num: 1,
            user: null,
            state: false,//状态
        })
        const click = useCallback(() => {
            const url = process.env.WEBSOCKET_BASE_URL + asPath.slice(asPath.lastIndexOf("/"))
            client(url, {
                "command": "join",
                "roomid": room,
            })
        }, [room, send])
        useEffect(() => {//游戏在匹配ing
            if (!message) return;
            switch (message.command) {
                case "join":    
                    setUserState({ ...userState, user: message.pid })
                    break;
                case "wait":
                    setUserState({ ...userState, num: message.num, state: false })
                    break;
                case "start":
                    setUserState({ state: true, num: maxNumber, user: message.pid })
                    break;
                case "leave"://跑路
                    close()
                    break;
                case "giveup"://放弃

                    break;
            }
        }, [message])
        if (!userState.state || !state) {
            //准备状态时
            const match = state ? <Match
                maxNumber={maxNumber}
                current={userState.num}
            /> : null
            return (
                <ConnectCard>
                    <h1>输入房间名进行匹配</h1>
                    <Input.Search
                        value={room}
                        onChange={({ target }) => setRoom(target.value)}
                        onSearch={click}
                    />
                    {match}
                </ConnectCard>
            )
        }
        return (
            <Component
                {...props}
                message={message}
                userState={userState}
                send={send}
                close={close}
            />
        )
    }
    return result
}